package org.example.util;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.SignatureException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.example.config.FmFrontedProperties;
import org.example.domain.beans.JwtParseInfo;
import org.springframework.stereotype.Component;

import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
@Component
public class FmFrontedJwtUtils {
    private Log log= LogFactory.getLog(FmFrontedJwtUtils.class);
    public final static String ACCESS_TOKEN_KEY="access_token";
    public final static String REFRESH_TOKEN_KEY="refresh_token";
    private Key accessKey;
    private Key refreshKey;
    private long accessJwtExpire;
    private long refreshJwtExpire;

    public String createAccessToken(String username){
        return createToken(username,accessJwtExpire,accessKey);
    }
    public String createRefreshToken(String username){
        return createToken(username,refreshJwtExpire,refreshKey);

    }
    //验证access_token
    public JwtParseInfo validateAccessJwt(String jwt){
        return validateJwt(jwt,accessKey);
    }
    //验证refresh_token
    public JwtParseInfo validateRefreshJwt(String jwt){
        return validateJwt(jwt,refreshKey);
    }

    //验证token
    private JwtParseInfo validateJwt(String jwt, Key key){
        JwtParseInfo jwtParseInfo=new JwtParseInfo();
        try{
            Claims claims=Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(jwt).getBody();
            log.info(claims.getAudience());
            jwtParseInfo.setClaims(claims);
            jwtParseInfo.setSignatureStatus(FmFrontedSignatureStatus.correct);
            return jwtParseInfo;//正常
        }catch (ExpiredJwtException exception ){
            log.info("jwt过期了");
            jwtParseInfo.setSignatureStatus(FmFrontedSignatureStatus.expired);
            return jwtParseInfo;
        } catch (MalformedJwtException | SignatureException | UnsupportedJwtException exception){
            log.error("jwt异常,可能被篡改了*");
            jwtParseInfo.setSignatureStatus(FmFrontedSignatureStatus.tamper);
            return jwtParseInfo;

        }
    }

    public FmFrontedJwtUtils(FmFrontedProperties fmFrontedProperties) {
        this.accessKey=new SecretKeySpec(Base64.getDecoder().decode(fmFrontedProperties.getJwt().getAccessKey()),"HmacSHA512");
        this.refreshKey=new SecretKeySpec(Base64.getDecoder().decode(fmFrontedProperties.getJwt().getRefreshKey()),"HmacSHA512");
        this.accessJwtExpire= fmFrontedProperties.getJwt().getAccessJwtExpire();
        this.refreshJwtExpire= fmFrontedProperties.getJwt().getRefreshJwtExpire();
    }

    /**
     * 创建token
     * @param username 用户名
     * @param expire  jwt的过期时间
     * @param key 是用来签名的，就是用来封装签名字符串
     * @return
     */
    private String createToken(String username, long expire, Key key){
        return Jwts.builder()
                .setSubject(username)//设置当前jwt用于谁
                .setIssuedAt(new Date())//设置Jwt的创建时间
                .setExpiration(new Date(System.currentTimeMillis()+expire))//设置过期时间
                .signWith(key, SignatureAlgorithm.HS512)
                .compact();//返回签名对应的字符串
    }

}
